#include <iostream>
#include <memory>
#include <dlfcn.h>
#include "happy.h"

using namespace wml;


// 定义动态库内的函数类型
typedef int (*add_type)(int, int);
typedef Person * (*createPersonFuncPtr)(const std::string , u_int8_t);
typedef void (*releasePersonFuncPtr)(Person * p);
typedef ProfileClient * (*getProfileClientFuncPtr)();

int main(int argc, char * argv[]) {

    // 加载动态库
    void * handle = dlopen("./sub_dir1/libhappy.so", RTLD_LAZY);

    if (!handle) {
        std::cout << "dlopen error! "<< dlerror() <<  std::endl;
        dlclose(handle);
        return 0;
    }
    // 取动态库内的 add 函数
    add_type add = (add_type)dlsym(handle, "add");
    createPersonFuncPtr createPerson = (createPersonFuncPtr)dlsym(handle, "createPerson");
    releasePersonFuncPtr releasePerson = (releasePersonFuncPtr)dlsym(handle, "releasePerson");
    getProfileClientFuncPtr getProfileClient = (getProfileClientFuncPtr)dlsym(handle, "GetProfileClientInstance");

    if (!add) {
        std::cout << "dlsym error! " << dlerror() << std::endl;
        dlclose(handle);
        return 0;
    }
    
    // 调用实例方法
    auto * p = createPerson("wml", 20);
    p->run();
    

    // 调用单例类的方法
    auto * p1 = getProfileClient();
    p1->LogInfo();
    
    
    // std::cout << "add " << add << " " << handle << std::endl;
    std::cout << "3 + 5 = " << add(3, 5) << std::endl;

    // 关闭动态库
    releasePerson(p);
    dlclose(handle);
    return 0;
}
